﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AK.FTP
{
    public partial class FrmMain : Form
    {
        private Shell32.Folder m_RootShell;
        private Shell32.Folder m_currentFolder;
        private Shell32.Shell m_Shell;
        private Icon m_IconFolder;
        private TaskHelper m_taskHelper;

        private static FtpHelper m_FtpHelper = null;

        private static object _lockObject = new object();

        public FrmMain()
        {
            InitializeComponent();

            m_taskHelper = new TaskHelper();
        }

        private void FillLocalView(Shell32.Folder folder)
        {

            this.Cursor = Cursors.WaitCursor;

            m_currentFolder = folder;
            // Notify that update begins
            lstLocal.BeginUpdate();

            // Erase last view items
            lstLocal.Items.Clear();

            // Erase previous lists image
            ImgListViewSmall.Images.Clear();
            ImgListViewLarge.Images.Clear();

            int idImage = 0;

            ListViewItem lvItem = new ListViewItem("..");
            lvItem.Tag = folder;

            lstLocal.Items.Add(lvItem);

            Shell32.FolderItems items = folder.Items();

            // Folder enumeration
            foreach (Shell32.FolderItem item in items)
            {
                if (item.IsFolder)
                {
                    AddViewItem(item, ref idImage);
                }
            }

            // Other files 
            foreach (Shell32.FolderItem item in items)
            {
                if (!item.IsFolder)
                {
                    AddViewItem(item, ref idImage);
                }
            }

            // End update view
            lstLocal.EndUpdate();

            //ftpc.LocalFolder = folder.Title;

            this.Cursor = Cursors.Default;

        }

        private void AddComboBoxItem(Shell32.FolderItem item, ref int idImage)
        {

        }

        private void AddViewItem(Shell32.FolderItem item, ref int idImage)
        {
            string[] sValues = new string[10];

            sValues[0] = item.Name;
            if (item.Size == 0)
                sValues[1] = "";
            else
                sValues[1] = Convert.ToString(item.Size / 1024) + " KB";
            sValues[2] = item.Type;
            sValues[3] = item.ModifyDate.ToString();
            /*
            sValues[4] = item.Path;
            sValues[5] = item.IsBrowsable.ToString();
            sValues[6] = item.IsFileSystem.ToString();
            sValues[7] = item.IsFolder.ToString();
            sValues[8] = item.IsLink.ToString();
            */
            ImgListViewSmall.Images.Add(ExtractIcon.GetIcon(item.Path, true));

            ListViewItem lvItem = new ListViewItem(sValues, idImage++);
            lvItem.Tag = item;
            lstLocal.Items.Add(lvItem);
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            Initialize();
        }

        private void InitializeIconFolder()
        {
            Shell32.Folder FolderShell = m_Shell.NameSpace(Shell32.ShellSpecialFolderConstants.ssfWINDOWS);
            Shell32.FolderItems items = FolderShell.Items();

            foreach (Shell32.FolderItem item in items)
            {
                if (item.IsFolder)
                {
                    m_IconFolder = ExtractIcon.GetIcon(item.Path, true);
                    break;
                }
            }
        }

        private void Initialize()
        {
            m_Shell = new Shell32.ShellClass();
            m_RootShell = m_Shell.NameSpace(Shell32.ShellSpecialFolderConstants.ssfDRIVES);

            InitializeIconFolder();
            FillLocalView(m_RootShell);
        }

        private void InitializeCombobox(Shell32.Folder folder)
        {
            int idImage = 0;
            Shell32.FolderItems items = folder.Items();

            // Folder enumeration
            foreach (Shell32.FolderItem item in items)
            {
                if (item.IsFolder)
                {
                    AddViewItem(item, ref idImage);
                }
            }

            // Other files 
            foreach (Shell32.FolderItem item in items)
            {
                if (!item.IsFolder)
                {
                    AddViewItem(item, ref idImage);
                }
            }
        }

        private void lstLocal_ItemActivate(object sender, EventArgs e)
        {
            if (lstLocal.SelectedItems[0].Text == "..")
            {
                Shell32.Folder item;

                item = (Shell32.Folder)lstLocal.SelectedItems[0].Tag;
                FillLocalView((Shell32.Folder)item.ParentFolder);
                //Shell32.FolderItem f = (m_currentFolder as Shell32.FolderItem);
            }
            else
            {
                Shell32.FolderItem item;

                item = (Shell32.FolderItem)lstLocal.SelectedItems[0].Tag;
                if (item.IsFolder)
                {
                    FillLocalView((Shell32.Folder)item.GetFolder);
                }
                cboLocal.Text = item.Path;
            }
        }

        private void copy_CToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new FrmFileSync().ShowDialog();
        }

        private void cboLocal_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter && !string.IsNullOrEmpty(cboLocal.Text))
            {
                Shell32.Folder item = m_Shell.NameSpace(cboLocal.Text);
                FillLocalView(item);
            }
        }

        //连接
        private void btnConnect_ButtonClick(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(cboServerUrl.Text) ||
                string.IsNullOrEmpty(txtUserName.Text) ||
                string.IsNullOrEmpty(txtPassword.Text) ||
                string.IsNullOrEmpty(txtPort.Text))
            {
                return;
            }
            this.Cursor = Cursors.WaitCursor;
            try
            {
                DisplayLog(string.Format("正在连接 [{0}]", cboServerUrl.Text));
                m_FtpHelper = new FtpHelper(new Uri(cboServerUrl.Text), txtUserName.Text, txtPassword.Text);
                DisplayLog(string.Format("连接成功[{0}]", cboServerUrl.Text));
                FileStruct[] files = m_FtpHelper.ListFilesAndDirectories();
                FillFtpView(files);

                btnDisconnect.Enabled = true;
                btnSync.Enabled = true;
            }
            catch (Exception)
            {
                this.Cursor = Cursors.Default;
                DisplayLog(m_FtpHelper.ErrorMsg, MessageTypeEnum.Error);
                return;
            }

            this.Cursor = Cursors.Default;
        }

        //显示服务器文件列表
        private void FillFtpView(FileStruct[] files)
        {
            int idimage = 0;
            lstServer.BeginUpdate();
            lstServer.Items.Clear();

            if (!m_FtpHelper.DirectoryPath.Equals("/"))
            {
                lstServer.Items.Add("..");
            }

            ImgListServerSmall.Images.Clear();
            foreach (var fileStruct in files)
            {
                if (fileStruct.IsDirectory)
                {
                    string[] items = new String[4];
                    items[0] = fileStruct.Name;
                    items[1] = string.Empty;
                    items[2] = string.Empty;
                    items[3] = fileStruct.CreateTime.ToString();
                    ImgListServerSmall.Images.Add(m_IconFolder);
                    lstServer.Items.Add(new ListViewItem(items, idimage++) { Tag = fileStruct });
                }
            }

            foreach (var fileStruct in files)
            {
                if (!fileStruct.IsDirectory)
                {
                    string[] items = new String[4];
                    items[0] = fileStruct.Name;
                    items[2] = string.Empty;
                    items[3] = fileStruct.CreateTime.ToString();

                    ImgListServerSmall.Images.Add(ExtractIcon.GetIcon(m_FtpHelper.Uri.AbsolutePath + "\\" + items[0], false));
                    lstServer.Items.Add(new ListViewItem(items, idimage++) { Tag = fileStruct });
                }
            }

            lstServer.EndUpdate();
            DisplayLog(m_FtpHelper.DirectoryPath + "  列表显示完成");
        }

        private void lstServer_ItemActivate(object sender, EventArgs e)
        {
            if (lstServer.SelectedItems.Count == 0)
            {
                return;
            }
            this.Cursor = Cursors.WaitCursor;
            if (lstServer.SelectedItems[0].Text == "..")
            {
                try
                {
                    m_FtpHelper.ComeoutDirectory();
                    FileStruct[] files = m_FtpHelper.ListFilesAndDirectories();
                    FillFtpView(files);
                }
                catch
                {
                    DisplayLog(m_FtpHelper.ErrorMsg, MessageTypeEnum.Error);
                }

            }
            else
            {
                FileStruct fileStruct = (FileStruct)lstServer.SelectedItems[0].Tag;
                if (fileStruct.IsDirectory)
                {
                    try
                    {
                        m_FtpHelper.GotoDirectory(fileStruct.Name);
                        FileStruct[] files = m_FtpHelper.ListFilesAndDirectories();
                        FillFtpView(files);
                    }
                    catch
                    {
                        DisplayLog(m_FtpHelper.ErrorMsg, MessageTypeEnum.Error);
                    }

                }
            }
            this.Cursor = Cursors.Default;
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            m_FtpHelper = null;
            btnDisconnect.Enabled = false;
            btnSync.Enabled = false;
            lstServer.Items.Clear();
            DisplayLog("已断开连接");
        }

        //显示日志记录
        private void DisplayLog(string msg, MessageTypeEnum type)
        {
            msg = string.Format("[{0}]{1}", DateTime.Now, msg);
            if (string.IsNullOrEmpty(msg))
                return;

            if (txtLog.Text.Length == 0)
            {
                txtLog.Text = msg;
            }
            else
            {
                txtLog.Text += "\r\n" + msg;
            }

            txtLog.SelectionStart = 0;
            txtLog.SelectionLength = msg.Length - 1;
            txtLog.SelectionColor = type == MessageTypeEnum.Error ? Color.Red : Color.DodgerBlue;
        }

        private void DisplayLog(string msg)
        {
            DisplayLog(msg, MessageTypeEnum.Normal);
        }

        private void BeginSync(Shell32.Folder folder)
        {
            Shell32.FolderItems items = folder.Items();
            foreach (Shell32.FolderItem item in items)
            {
                if (item.IsFolder)
                {
                    BeginSync((Shell32.Folder)item.GetFolder);
                }
                else
                {
                    string localPath = cboLocal.Text;
                    Task task = new Task(() => BeginSyncFile(item, localPath));
                    m_taskHelper.NewTask(task);
                    //BeginSyncFile(item);
                }
            }
        }

        private void BeginSyncFile(Shell32.FolderItem item,string localPath)
        {
            //m_FtpHelper.GotoDirectory(item.Path)
            string filePath = item.Path.Replace(localPath, "").Replace(item.Name, "").Replace("\\", "/");
            lock (_lockObject)
            {
                m_FtpHelper.GotoDirectory(filePath);
                if (m_FtpHelper.FileExist(item.Name))
                {
                    DisplayLog(string.Format("开始下载文件[{0}]...", item.Name));
                    m_FtpHelper.DownloadFileAsync(item.Name, item.Path + "\\" + item.Name);
                    m_FtpHelper.DownloadProgressChanged +=
                        new FtpHelper.De_DownloadProgressChanged(m_FtpHelper_DownloadProgressChanged);
                    m_FtpHelper.DownloadDataCompleted +=
                        new FtpHelper.De_DownloadDataCompleted(m_FtpHelper_DownloadDataCompleted);
                }
            }
        }

        void m_FtpHelper_DownloadDataCompleted(object sender, AsyncCompletedEventArgs e)
        {
            
        }

        void m_FtpHelper_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            
        }

        private void btnSync_Click(object sender, EventArgs e)
        {
            if (m_FtpHelper == null)
                return;
            if (m_currentFolder == null)
                return;

            DisplayLog("开始同步");
            this.Invoke((MethodInvoker)delegate
                {
                    BeginSync(m_currentFolder);
                    DisplayLog("同步完成");
                });

        }

        private void vSS_VToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new FrmVssSync().ShowDialog();
        }
    }

    public enum MessageTypeEnum
    {
        Normal,
        Error
    }
}
